﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;
using System.Data;
using System.Data.OleDb;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.IO;

namespace TooltracePC
{
    public partial class frmUSB : Form
    {
        public const int C_RESULT_MESSAGE = 100;
        public const int C_MSG_TYPE_PROGRESS = 0;
        public const int C_MSG_TYPE_FINISHED = 1;
        public const int C_MSG_TYPE_ERROR = 2;
        public const int C_MSG_TYPE_REFRESH_FAIL = 3;
        public const int C_MSG_TYPE_FTP_SETTING = 4;

        public const int ESUCCESS = 0;
        public const int EINVALID_ARGS = -100;
        public const int EFILE_FORMAT_ERR = -101;
        public const int ETIMEOUT = -102;
        public const int EPROTOCOL = -103;
        public const int EFILEOPEN = -104;
        public const int EINIT = -105;
        public const int EDEVICE_INUSE = -106;
        public const int EDEVICE_NOT_EXIST = -107;
        public const int EWRITE_FAIL = -108;
        public const int EREAD_FAIL = -109;

        //Function Code
        public const int C_USB_PORT = 255;
        public const int FILE_NAME_LENGTH = 32;

        //用于brGetMachInfo及brSetMachInfo函数的iIndex参数
        public const int MACH_USER_PAS_ALL = 1;
        public const int MACH_USER_PAS_RUNFILE = 2;
        public const int MACH_USER_PAS_SELECT = 3;
        public const int MACH_USER_PAS_FILEINFO = 4;
        public const int MACH_USER_PAS_COMM = 5;
        public const int MACH_USER_PAS_FILEMAN = 6;
        public const int MACH_USER_PAS_SYSTEM = 7;
        public const int MACH_USER_COMPANY_NAME = 8;
        public const int MACH_USER_USER_NAME = 9;
        public const int MACH_USER_USER_NO = 10;
        public const int MACH_USER_MACH_NO = 11;
        public const int MACH_USER_REMARK = 12;

        //用于brGetMachInfo及brSetMachInfo函数的iIndex参数
        public const int MACH_SYS_MEM_CAPACITY = 1;
        public const int MACH_SYS_FILE_COUNT = 2;
        public const int MACH_SYS_ROOM_OCCUR = 3;
        public const int MACH_SYS_MACHINE_VER = 4;
        public const int MACH_SYS_MACHINE_TYPE = 5;
        public const int MACH_SYS_MACHINE_NO = 6;
        public const int MACH_SYS_COMPANY_NAME = 7;

        //用于实现进度条显示  
        public const int PROGRESS_NONE = 0;
        public const int PROGRESS_CALLBACK = 1; //由用户提供函数，由动态库调用
        public const int PROGRESS_HWND = 2;  //由用户提供父窗口句柄，动态库显示进度
        public const int PROGRESS_MESSAGE = 3;  //由用户提供父窗口句柄，动态库向此窗口发送消息

        //用于brUploadMemory及brDownloadMemory函数的cMode参数
        public const int MEM_OP_MODE_SPECIAL = 0;
        public const int MEM_OP_MODE_OS = 1;
        public const int MEM_OP_MODE_HZ_INPUT = 2;
        public const int MEM_OP_MODE_ICON = 3;
        public const int MEM_OP_MODE_RUN_RAM = 4;
        public const int MEM_OP_MODE_RUN_ROM = 5;
        public const int MEM_OP_MODE_MACH_PARA = 6;
        public const int MEM_OP_MODE_MACH_SOUND = 7;


        //datetime struct
        public struct S_BR_DATETIME
        {
            public byte cYear, cMonth, cDate;
            public byte cHour, cMin, cSec;
        }

        //file list struct
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        struct S_BR_FILE_INFO
        {
            public uint iFileLength;
            public uint iFileNo;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string szFileName;
            public S_BR_DATETIME stCreateDateTime;
            public S_BR_DATETIME stModifyDateTime;
        }

        //
        struct S_BR_MACH_LIST_INFO
        {
            public uint iPortNo;
            public uint iInstanceNo;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
            public string szDeviceName;
        }


        //
        public const int SETP_TASK = 6;
        public static int nPort = -1;
        private int _currentTask = 1;
        private int _OP = 0;
        private int nExe = 0;
        private int nValue = 0;
        private string _errMsg = "";

        private int _pos = 0;
        private int _stop = 0;
        //private string[] _delTask;
        List<string> _delTask = new List<string>();
        private int _del = 0;



        public delegate void SetProgress(int value);

        //function 
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brSetProgress(int i_method, IntPtr hwnd_proc);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brCheckPort();

        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brGetMachInfo(int iPortNo, int index, IntPtr pMachInfo);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brGetMachSysInfo(int iPortNo, int index, IntPtr pMachInfo);

        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brGetNormalFileList(int iPortNo, IntPtr outArray, ref int piCount);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brDeleteFile(int iPortNo, string filename);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brCompleteDelFile(int iPortN, string filename);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brUploadFile(int iPortN, string filename, string pcname);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brDownloadFile(int iPortN, string sPcFileName, string sHcFileName);
        [DllImport("brcomm.dll", SetLastError = true)]
        private static extern int brGetErrMsg(int errcode, char[] p_msg, ref int p_cango);


       


        //initBrcomm
        public void initComm()
        {

            SetProgress callback = new SetProgress(setPBValue);
            IntPtr P = Marshal.GetFunctionPointerForDelegate(callback); //获取函数指针
            brSetProgress(PROGRESS_CALLBACK, P);
        }


        private void setPBValue(int value)
        {
            pbUsb.Value = value;
            nValue = value;
            
        }

        //check connetion
        public int checkConn()
        {
            nPort = brCheckPort();
            if (EDEVICE_NOT_EXIST == nPort)
            {
                return 0;
            }
            initComm();
            return 1;
        }


        //send file to handset
        public int sendFileToHandset(string filename, int nMsg)
        {
            if (checkConn() == 0)
            {
                if (nMsg == 1)
                {
                    MessageBox.Show("手持设备未连接", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }

            int ErrCode = brDownloadFile(nPort, filename, filename);

            if (ErrCode != ESUCCESS)
            {
                if (nMsg == 1)
                {
                    int pcango = 0;
                    char[] msg = new char[255];
                    brGetErrMsg(ErrCode, msg, ref pcango);
                    string strMsg = new string(msg);
                    MessageBox.Show(ErrCode.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }
            return 1;
        }


        //delete 
        public int delFileInHandset(string fileName, int nMsg)
        {
            if (checkConn() == 0)
            {
                if (nMsg == 1)
                {
                    MessageBox.Show("手持设备未连接", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }

            int ErrCode = brDeleteFile(nPort, fileName);
            if (ErrCode != ESUCCESS)
            {
                if (nMsg == 1)
                {
                    int pcango = 0;
                    char[] msg = new char[255];
                    brGetErrMsg(ErrCode, msg, ref pcango);
                    string strMsg = new string(msg);
                    MessageBox.Show(ErrCode.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }
            return 1;
        }


        //down file
        public int getFileOnHandset(string filename, string saveName ,int nMsg)
        {
            if (checkConn() == 0)
            {
                if (nMsg == 1)
                {
                    MessageBox.Show("手持设备未连接", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }

            int ErrCode = brUploadFile(nPort, filename, saveName);

            if (ErrCode != ESUCCESS)
            {
                if (nMsg == 1)
                {
                    int pcango = 0;
                    char[] msg = new char[255];
                    brGetErrMsg(ErrCode, msg, ref pcango);
                    string strMsg = new string(msg);
                    MessageBox.Show(ErrCode.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return 0;
            }
            return 1;
        }


        //get file list
        public string[] getFileList(int nMsg)
        {
            string[] FileList = null;
            if (checkConn() == 0)
            {
                if (nMsg == 1)
                {
                    MessageBox.Show("手持设备未连接", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return FileList;
            }

            try
            {
                int count = 200;
                int size = Marshal.SizeOf(typeof(S_BR_FILE_INFO));
                IntPtr infosIntptr = Marshal.AllocHGlobal(size * count);

                int k = brGetNormalFileList(nPort, infosIntptr, ref count);


                if (k != ESUCCESS)
                {
                    return FileList;
                }

                S_BR_FILE_INFO[] files = new S_BR_FILE_INFO[count];
                FileList = new string[count];

                for (int i = 0; i < count; i++)
                {
                    IntPtr ptr = (IntPtr)((UInt32)infosIntptr + i * size);
                    files[i] = (S_BR_FILE_INFO)Marshal.PtrToStructure(ptr, typeof(S_BR_FILE_INFO));
                }

                Marshal.FreeHGlobal(infosIntptr);

                int j = 0;
                foreach (S_BR_FILE_INFO file in files)
                {
                    FileList[j++] = file.szFileName;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return FileList;
        }

        //del sync
        private void delSync()
        {
            string strPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "datas\\";
            string strFileName = "sync.dbf";
            int i = 0;
            if (_pos == -1)
            {
                tsLb.Text = "正在同步：" + strFileName;
                _pos++;
                i = sendFileToHandset(strPath + strFileName, 0);
            }
            else
            {
                if (_delTask.Count > 0)
                {
                    if (_pos < _delTask.Count)
                    {
                        tsLb.Text = "正在删除：" + _delTask[_pos];
                        i = delFileInHandset(_delTask[_pos++], 0);
                    }
                    else
                    {
                        tmValue.Enabled = false;
                        delDirAll();
                        endForm();
                    }
                }
                else
                {
                    tmValue.Enabled = false;
                    delDirAll();
                    endForm();
                }
            }

        }

        //del dir
        private void delDirAll()
        {
            string strPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "datas";
            Directory.Delete(strPath, true);
            Directory.CreateDirectory(strPath);
        }


        //sync
        private void syncData()
        {
            string strPath = AppDomain.CurrentDomain.BaseDirectory.ToString();
            int i = 0;
            string strFileName = "";

            nValue = 0;

            _errMsg = "总任务：" + SETP_TASK + ",";
            if (_currentTask == 1)
            {//setp 1
                strFileName = "template\\synctmp.dbf";
                tsLb.Text = "正在同步：" + strFileName;
                i = sendFileToHandset(strPath + strFileName, 0); 
            }
            else if (_currentTask == 2)
            {//setp 1
                strFileName = "template\\out.dbf";
                tsLb.Text = "正在同步：" + strFileName;
                i = sendFileToHandset(strPath + strFileName, 1);
            }
            else if(_currentTask == 3)
            {
                tsLb.Text = "正在生成tool.dbf";
                generateToolDbf();
                strFileName = "template\\tool.dbf";
                tsLb.Text = "正在同步：" + strFileName;
                i = sendFileToHandset(strPath + strFileName, 1);
            }
            else if(_currentTask == 4)
            {
                tsLb.Text = "正在生成user.dbf";
                generateUserDbf();
                strFileName = "template\\user.dbf";
                tsLb.Text = "正在同步：" + strFileName;
                i = sendFileToHandset(strPath + strFileName, 1);
            }
            else if(_currentTask == 5)
            {
                strFileName = "datas\\sync.dbf";
                tsLb.Text = "正在同步：" + strFileName;
                //byte[] byteArray = Encoding.Default.GetBytes("sync.dbf");
                i = getFileOnHandset("sync.dbf", strPath + strFileName, 1);

            }
            else if(_currentTask == 6)
            {
                strFileName = "sync.dbf";
                if (File.Exists(strPath + "datas\\" + strFileName))
                {
                    _stop = 1;
                    dbf objectDbf = new dbf(strPath + "datas\\");
                    DataTable dt = null;
                    dt = objectDbf.getAll(strFileName);
                   
                    //byte[] byteArray = null;
                    if (_pos < dt.Rows.Count)
                    {
                        if(int.Parse(dt.Rows[_pos]["FILESTATUS"].ToString()) > 0)
                        {
                            strFileName = dt.Rows[_pos]["FILENAME"].ToString().Trim();
                            tsLb.Text = "正在同步：" + strFileName;
                            //byteArray = Encoding.Default.GetBytes(strFileName.Trim());
                            i = getFileOnHandset(strFileName, strPath + "datas\\" + strFileName, 0);
                        }
                        else
                        {
                            nValue = 100;
                        }
                    }
                    else
                    {
                        _stop = 0;
                        _pos = 0;
                        nValue = 100;
                    }
                }
            }
            else if (_currentTask == SETP_TASK + 1)
            {
                nValue = 100;
            }
        
        }


        //proc sync data
        public void procSyncData()
        {
            string strPath = AppDomain.CurrentDomain.BaseDirectory.ToString();
            string strFileName = "";
            int n;

            strFileName = "sync.dbf";
            tsLb.Text = "正在处理：" + strFileName;
           
            if (!File.Exists(strPath + "datas\\" + strFileName))
            {
                MessageBox.Show(strFileName+ "文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            dbf objectDbf = new dbf(strPath + "datas\\");
            DataTable dt = null;
            dt = objectDbf.getAll("sync");

            DataTable dtResutl = null;
            
            dbSync syncDB = new dbSync();
            int i, j, nR;
            for(i = 0; i < dt.Rows.Count; i++)
            {
                if (int.Parse(dt.Rows[i]["FILESTATUS"].ToString()) == 0) { continue; }
                strFileName = dt.Rows[i]["FILENAME"].ToString().Trim();
                dtResutl = syncDB.getByFileName(strFileName);

                if(dtResutl.Rows.Count == 0)
                {//add
                    DataTable dtRecords = null;
                    dtRecords = objectDbf.getAll(strFileName);
                    for(j = 0; j < dtRecords.Rows.Count; j++)
                    {
                        nR = syncDB.insertSyncData(strFileName, dtRecords.Rows[j]["标签ID"].ToString().Trim(), dtRecords.Rows[j]["名称"].ToString().Trim(), dtRecords.Rows[j]["编码"].ToString().Trim(), dtRecords.Rows[j]["出库"].ToString().Trim(), dtRecords.Rows[j]["出库人姓名"].ToString().Trim(), dtRecords.Rows[j]["出库时间"].ToString().Trim(), dtRecords.Rows[j]["清点一"].ToString().Trim(), dtRecords.Rows[j]["清点一姓名"].ToString().Trim(), dtRecords.Rows[j]["清点一时间"].ToString().Trim(), dtRecords.Rows[j]["清点二"].ToString().Trim(), dtRecords.Rows[j]["清点二姓名"].ToString().Trim(), dtRecords.Rows[j]["清点二时间"].ToString().Trim(), dtRecords.Rows[j]["入库"].ToString().Trim(), dtRecords.Rows[j]["入库人姓名"].ToString().Trim(), dtRecords.Rows[j]["入库时间"].ToString().Trim(), dtRecords.Rows[j]["md"].ToString().Trim(), dtRecords.Rows[j]["note"].ToString().Trim());
                    }
                    //insert sync
                    nR = syncDB.insertDb(int.Parse(dt.Rows[i]["ID"].ToString()), dt.Rows[i]["CREATEMAN"].ToString().Trim(), dt.Rows[i]["CREATEDATE"].ToString().Trim(), dt.Rows[i]["CREATETIME"].ToString().Trim(), strFileName, int.Parse(dt.Rows[i]["FILESTATUS"].ToString()), dt.Rows[i]["FileStamp"].ToString().Trim());
                    //_delTask
                    if(int.Parse(dt.Rows[i]["FILESTATUS"].ToString()) == 5)
                    {
                        _delTask.Add(strFileName);//已完成，添加到删除任务
                    }
                }
                else
                {//update
                    if (int.Parse(dtResutl.Rows[0]["FILESTATUS"].ToString()) == 5)//手动完成
                    {
                        _delTask.Add(strFileName);//已手动完成，添加到删除任务
                    }
                    else
                    {
                        //文件已发生变化
                        if (dtResutl.Rows[0]["FILESTAMP"].ToString().Trim() != dt.Rows[i]["FileStamp"].ToString().Trim())
                        {
                            //清除原记录，生成新记录
                            n = syncDB.delSyncData(strFileName);
                            DataTable dtRecords = null;
                            dtRecords = objectDbf.getAll(strFileName);
                            for (j = 0; j < dtRecords.Rows.Count; j++)
                            {
                                nR = syncDB.insertSyncData(strFileName, dtRecords.Rows[j]["标签ID"].ToString().Trim(), dtRecords.Rows[j]["名称"].ToString().Trim(), dtRecords.Rows[j]["编码"].ToString().Trim(), dtRecords.Rows[j]["出库"].ToString().Trim(), dtRecords.Rows[j]["出库人姓名"].ToString().Trim(), dtRecords.Rows[j]["出库时间"].ToString().Trim(), dtRecords.Rows[j]["清点一"].ToString().Trim(), dtRecords.Rows[j]["清点一姓名"].ToString().Trim(), dtRecords.Rows[j]["清点一时间"].ToString().Trim(), dtRecords.Rows[j]["清点二"].ToString().Trim(), dtRecords.Rows[j]["清点二姓名"].ToString().Trim(), dtRecords.Rows[j]["清点二时间"].ToString().Trim(), dtRecords.Rows[j]["入库"].ToString().Trim(), dtRecords.Rows[j]["入库人姓名"].ToString().Trim(), dtRecords.Rows[j]["入库时间"].ToString().Trim(), dtRecords.Rows[j]["md"].ToString().Trim(), dtRecords.Rows[j]["note"].ToString().Trim());
                            }
                            //更新sync
                            n = syncDB.updateSync(strFileName, int.Parse(dt.Rows[i]["FILESTATUS"].ToString()), dt.Rows[i]["FileStamp"].ToString().Trim());
                            if (int.Parse(dt.Rows[i]["FILESTATUS"].ToString()) == 5)
                            {
                                _delTask.Add(strFileName);//已完成，添加到删除任务
                            }
                            
                        }
                    }
                }
               
            }

            
            if(_delTask.Count > 0)
            {
                tsLb.Text = "正在生成：sync.dbf";
                string sql;
                for (i = 0; i < _delTask.Count; i++)
                {
                    sql = @"delete from sync where FILENAME = '"+ _delTask[i] + "'";
                    n = objectDbf.executeNonQuery(sql);
                }
                sql = @"Pack sync";
                i = objectDbf.executeNonQuery(sql);

                //执行删除
                nValue = 100;
                _del = 1;
                _pos = -1;
                tmValue.Enabled = true;
            }
            else
            {
                tmValue.Enabled = false;
                delDirAll();

                endForm();
            }

            //endForm();
        }


    

        //build tool.dbf
        private int generateToolDbf()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
            dbf objectDbf = new dbf(path + "template");

            string sql = "";
            int i = 1;
            sql = @"delete from tool";

            i = objectDbf.executeNonQuery(sql);
           
            sql = @"Pack tool";
            i = objectDbf.executeNonQuery(sql);

            dbTool ToolDb = new dbTool();
            DataTable dtTool = null;
            dtTool = ToolDb.getAll();

            for (int j = 0; j < dtTool.Rows.Count; j++)
            {
                sql = "insert into tool(标签ID, 名称, 编码) values('" + dtTool.Rows[j]["LableID"].ToString() + "', '" + dtTool.Rows[j]["LableName"].ToString() + "', '" + dtTool.Rows[j]["LableNo"].ToString() + "')";

                i = objectDbf.executeNonQuery(sql);
            }

            return i;
        }

        //build tool.dbf
        private int generateUserDbf()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
            dbf objectDbf = new dbf(path + "template");

            string sql = "";
            int i = 1;
            sql = @"delete from user";

            i = objectDbf.executeNonQuery(sql);

            sql = @"Pack user";
            i = objectDbf.executeNonQuery(sql);

            dbUser StaffDb = new dbUser();
            DataTable dt = null;
            dt = StaffDb.getAll2();

            for (int j = 0; j < dt.Rows.Count; j++)
            {
                sql = "insert into user(标签ID, 工号, 姓名, 密码, 权限) values('" + dt.Rows[j]["LableID"].ToString() + "', '" + dt.Rows[j]["UserNo"].ToString() + "', '" + dt.Rows[j]["UserName"].ToString() + "', '"+ dt.Rows[j]["UserPass"].ToString() + "', '"+ dt.Rows[j]["UserPower"].ToString() + "')";
 
                i = objectDbf.executeNonQuery(sql);
            }

            return i;
        }


        //form
        public frmUSB()
        {
            InitializeComponent();
        }


        public void setOP(int nOP)
        {
            _OP = nOP;
        }

        private void frmUSB_Load(object sender, EventArgs e)
        {
            this.Owner.Enabled = false;
            tmS.Enabled = true;
            nExe = 1;

            tmValue.Enabled = true;
        }

        private void frmUSB_Shown(object sender, EventArgs e)
        {
            
        }



        private void tmS_Tick(object sender, EventArgs e)
        {
            if(nExe == 1)
            {
                nExe = 0;
                if (_OP == 1)
                {
                    syncData();
                }

            }
            else
            {
                tmS.Enabled = false;
            }
        }

        private void endForm()
        {
            this.Owner.Enabled = true;
            dgv dgvObject = new dgv();
            dbSync syncDB = new dbSync();
            DataTable dt = new DataTable();
            dt = syncDB.getAll();
            dgvObject.setgDataSource(dt);
            this.Close();
        }

        private void frmUSB_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Owner.Enabled = true;
        }

        private void tmValue_Tick(object sender, EventArgs e)
        {
            if (nValue == 100 && _del == 0 && _currentTask <= SETP_TASK)
            {
                if (_stop == 0)
                {
                    _currentTask++;
                }
                else
                {
                    _pos++;
                }
                syncData();
            }
            else if (nValue == 100 && _del == 0 && _currentTask > SETP_TASK)
            {
                tmValue.Enabled = false;
                procSyncData();
            }
            else if (nValue == 100 && _del == 1)
            {
                delSync();
            }
        }
    }
}
